package org.darkforest.controller;

import com.alibaba.fastjson.JSONObject;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.darkforest.common.constant.Constants;
import org.darkforest.common.services.*;
import org.darkforest.common.util.CookieUtils;
import org.darkforest.common.util.DateUtil;
import org.darkforest.common.wxpay.utils.CorePushService;
import org.darkforest.common.wxpay.utils.XMLUtil;
import org.darkforest.dao.mapper.*;
import org.darkforest.enums.SettingNameEnum;
import org.darkforest.enums.VariablePrefixEnum;
import org.darkforest.model.*;
import org.darkforest.ucenter.auth.AuthPassport;
import org.darkforest.ucenter.service.MemberService;
import org.darkforest.vo.MemberBase;
import org.darkforest.vo.WxTextMessage;
import org.darkforest.vo.WxUserDetailInfo;
import org.darkforest.vo.WxUserInfo;
import org.jdom.JDOMException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;


/**
 * Created by Libing on 2015/3/30.
 */
@RestController
@RequestMapping(value = "wxPay")
@Api(value = "wxPay", description = "微信支付签名以及回调", produces = MediaType.APPLICATION_JSON_VALUE)
public class WeChatController {
    Logger logger = LoggerFactory.getLogger(WeChatController.class);

    @Autowired
    private WxJSSdkService wxJSSdkService;


    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    @Qualifier("wapMemberServiceImpl")
    private MemberService memberService;

//    @Autowired
//    private WebChatScanService scanService;               //扫描二维码获取推荐人信息操作类

    @Autowired
    private SettingService settingService;                  //获取配置信息

    @Autowired
    private SimpleRedisService redisService;


    @Autowired
    private ShoppingGroupMemberMapper shoppingGroupMemberMapper;

    @Autowired
    private ShoppingGroupMapper shoppingGroupMapper;


    @Autowired
    private PdRechargeService pdRechargeService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private PdRechargeMapper pdRechargeMapper;

    @Autowired
    private OrderPayMapper orderPayMapper;


    @RequestMapping(value = "notify", method = RequestMethod.POST)
    public void notify(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 将请求、响应的编码均设置为UTF-8（防止中文乱码）
//        request.setCharacterEncoding("UTF-8");
//        response.setCharacterEncoding("UTF-8");
        logger.info("###########微信支付成功消息推送###############");
        InputStream inStream = null;
        try {
            inStream = request.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        try {
            while ((len = inStream.read(buffer)) != -1) {
                outSteam.write(buffer, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            outSteam.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            inStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        String resultStr = null;
        try {
            resultStr = new String(outSteam.toByteArray(), "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        Map<String, String> resultMap = null;
        try {
            resultMap = XMLUtil.doXMLParse(resultStr);
        } catch (JDOMException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        String result_code = resultMap.get("result_code");
        String is_subscribe = resultMap.get("is_subscribe");
        String out_trade_no = resultMap.get("out_trade_no");
        String transaction_id = resultMap.get("transaction_id");
        String sign = resultMap.get("sign");
        String time_end = resultMap.get("time_end");
        String bank_type = resultMap.get("bank_type");
        String return_code = resultMap.get("return_code");
        //签名验证
        logger.info("result_code=" + result_code + "is_subscribe=" + is_subscribe + "out_trade_no=" + out_trade_no + "sign=" + sign + "time_end=" + time_end + "bank_type=" + bank_type + "return_code=" + return_code);

        //实际商户订单号
        String orderSn = out_trade_no.substring(0, out_trade_no.length() - 4);

        //微信jsapi支付
        OrderPay orderPay = orderPayMapper.selectByOrderSn(Long.parseLong(orderSn));
//            Order order = orderMapper.getOrderBySn(orderSn);
        List<OrderVo> orders = orderMapper.selectByOrderBatchNumber(orderSn);
        if (orders.size() > 0 && orders.get(0).getOrderState().equals("10")) {
            orderService.wxJsApiPayCallBack(orders, orderPay, bank_type, transaction_id, out_trade_no, orderSn);
        }

        //支付回调成功后 返回业务处理成功的标识给微信
        logger.info("支付回调成功后 返回业务处理成功的标识给微信#####" + DateUtil.getCurrentDateTime());
        String resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
        BufferedOutputStream out = new BufferedOutputStream(
                response.getOutputStream());
        out.write(resXml.getBytes());
        out.flush();
        out.close();
    }


    @AuthPassport
    @RequestMapping(value = "getwxOpenId")
    @ApiOperation(value = "根据微信服务器返回的code获取用户的openid", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    public RestEntity getwxOpenId(String code, String inMode) {
//        WxUserInfo userInfo = wxJSSdkService.getUserAccessToken(code);
//        WxUserDetailInfo userDetailInfo = wxJSSdkService.getUserDetail(userInfo.getAccess_token(), userInfo.getOpenid());
        WxUserInfo userInfo = new WxUserInfo();
        // 通过企业号进入时
        if ("qiye".equals(inMode)) {
            userInfo = wxJSSdkService.getQYUserAccessToken(code);
        } else {
            userInfo = wxJSSdkService.getUserAccessToken(code);
        }

        return RestEntity.success(userInfo.getOpenid());
    }


    @AuthPassport
    @RequestMapping(value = "orderSign")
    @ApiOperation(value = "微信支付签名", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    public RestEntity orderSign(HttpServletRequest request, String orderId, String payType, String openId) throws Exception {
        try {

            List<OrderVo> orders = orderMapper.selectByOrderBatchNumber(orderId);
            if (orders.size() > 0 && !"10".equals(orders.get(0).getOrderState())) {
                return RestEntity.failed("订单状态异常");
            }

//            Map<String, String> wxPayParamMap = wxJSSdkService.getJsApiPayParams(orders, openId, orderId);
            Map<String, String> wxPayParamMap = new TreeMap<String, String>();
            if ("1".equals(payType)) {
                wxPayParamMap = wxJSSdkService.getJsApiPayParams(orders, openId, orderId);
            } else {
                // 企业号进入
                wxPayParamMap = wxJSSdkService.getH5PayParams(request, orders, openId, orderId);
            }

            // 返回值的设定
            TreeMap signData = new TreeMap();
            signData.put("appId", wxPayParamMap.get("appId"));

            //  微信公众号支付用
            if ("1".equals(payType)) {
                signData.put("timeStamp", wxPayParamMap.get("timeStamp"));
                signData.put("nonceStr", wxPayParamMap.get("nonceStr"));
                signData.put("signature", wxPayParamMap.get("signature"));
                signData.put("wxPackage", wxPayParamMap.get("package"));
                signData.put("signType", wxPayParamMap.get("signType"));
                signData.put("paySign", wxPayParamMap.get("paySign"));
            }

            // H5支付用
            if ("2".equals(payType)) {
                signData.put("mwebUrl", wxPayParamMap.get("mweb_url"));
            }

            signData.put("goodsName", wxPayParamMap.get("goodsName"));

            return RestEntity.success(signData);
        } catch (Exception e) {
            return RestEntity.failed("支付异常");
        }
    }

    /**
     * 验证token
     *
     * @param request
     * @param response
     * @throws IOException
     */
    @RequestMapping(value = "validateToken", method = RequestMethod.GET)
    public void validateToken(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String token = settingService.getSettingInfo(SettingNameEnum.WXPAY_TOKEN);

        String signature = request.getParameter("signature");
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String echostr = request.getParameter("echostr");

        TreeMap<String, String> treeMap = new TreeMap<String, String>();
        treeMap.put("signature", signature);
        treeMap.put("token", token);
        treeMap.put("timestamp", timestamp);
        treeMap.put("nonce", nonce);
        boolean flag = wxJSSdkService.isWXSign(token, timestamp, nonce, signature);

        if (flag) {
            response.getWriter().print(echostr);
        } else {
            response.getWriter().print("");
        }
    }
}